
package com.zdkj.subway.stm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.injector.methods.SelectById;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdkj.admin.api.entity.SysDictItem;
import com.zdkj.common.core.constant.CommonConstants;
import com.zdkj.common.core.util.R;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.ObjectUtils;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.stm.constant.StmTableCommon;
import com.zdkj.subway.stm.dto.out.SwStTvmSupplementCurrencyDTO;
import com.zdkj.subway.stm.entity.*;
import com.zdkj.subway.stm.fegin.SystemUserService;
import com.zdkj.subway.stm.mapper.SwStTvmSupplementCurrencyMapper;
import com.zdkj.subway.stm.service.SwStTvmSupplementCurrencyDetailsService;
import com.zdkj.subway.stm.service.SwStTvmSupplementCurrencyService;
import com.zdkj.subway.stm.service.SwStmStationDataEntryLogService;
import com.zdkj.subway.stm.util.BeanUtilsStm;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.net.CookieHandler;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * TVM补币金额管理
 *
 * @author songtuo
 * @date 2020-07-09 10:33:25
 */
@Service
@AllArgsConstructor
public class SwStTvmSupplementCurrencyServiceImpl extends ServiceImpl<SwStTvmSupplementCurrencyMapper, SwStTvmSupplementCurrency> implements SwStTvmSupplementCurrencyService {

    @Autowired
    SwStTvmSupplementCurrencyDetailsService detailsService;

    private final SwStmStationDataEntryLogService swStmStationDataEntryLogService;

    @Override
    public boolean saveSwStTvmSupplementCurrency(SwStTvmSupplementCurrencyDTO supplementCurrencyDTO) {
        //1:复制主表的公共属性
        SwStTvmSupplementCurrency supplementCurrency = supplementCurrencyDTO.getSupplementCurrency();
        SwStTvmSupplementCurrency supplementCurrencyObj = ObjectUtils.getDefaultObj(SwStTvmSupplementCurrency.class);
        BeanUtil.copyProperties(supplementCurrencyObj, supplementCurrency, CopyOptions.create().setIgnoreNullValue(true));

        //2:复制从表的公共属性
        List<SwStTvmSupplementCurrencyDetails> details = supplementCurrencyDTO.getDetails();
        BeanUtilsStm.buildProperties(details);
        //3:统计总金额数
        if (CollectionUtil.isEmpty(details)) {
            return false;
        }
        countCoinAndPaperAmount(supplementCurrency, details);
        //4:保存主表
		//4.1.设置主表的更新人编号和名称，为报表差错做准备
		PigxUser user = SecurityUtils.getUser();           
        supplementCurrency.setEntryUpdateJobNo(user.getUserCode());
		supplementCurrency.setEntryUpdateJobName(user.getNikeName());		
        //保存主表
		save(supplementCurrency);
        //保存从表
        details.forEach(x -> {
            x.setRelationId(supplementCurrency.getId());
            //x.setTvmCashBoxNum(BeanUtilsStm.strRemoveBlank(x.getTvmCashBoxNum()));
        });
        detailsService.saveBatch(details);
        return true;
    }

    @Autowired
    SystemUserService systemUserService;
    /**
     * 统计总金额  补币纸币总金额  补币纸币总金额  合计总金额
     * @param supplementCurrency
     * @param details
     */
    private void countCoinAndPaperAmount(SwStTvmSupplementCurrency supplementCurrency, List<SwStTvmSupplementCurrencyDetails> details) {
        BigDecimal totalSupplementCoinAmount = new BigDecimal(0D);
        BigDecimal totalSupplementPaperAmount = new BigDecimal(0D);
        BigDecimal totalSupplementAmount = new BigDecimal(0D);
        for (SwStTvmSupplementCurrencyDetails detail : details) {
            BigDecimal supplementAmount = detail.getSupplementAmount();
            if (supplementAmount != null) {
                //判断钱箱类型 如果是硬币类型 叠加硬币 纸币类型 叠加纸币 硬币回收箱 12  纸币回收箱 3和4 5是废钞箱 只有纸票
                if (detail.getTvmCashBoxType().equals("1") || detail.getTvmCashBoxType().equals("2")) {
                    totalSupplementCoinAmount = totalSupplementCoinAmount.add(supplementAmount);
                }
                if (detail.getTvmCashBoxType().equals("3") || detail.getTvmCashBoxType().equals("4") || detail.getTvmCashBoxType().equals("5")) {
                    totalSupplementPaperAmount = totalSupplementPaperAmount.add(supplementAmount);
                }
            }
        }
        supplementCurrency.setTotalSupplementAmount( totalSupplementAmount.add(totalSupplementCoinAmount).add(totalSupplementPaperAmount));
        supplementCurrency.setTotalSupplementCoinAmount(totalSupplementCoinAmount);
        supplementCurrency.setTotalSupplementPaperAmount(totalSupplementPaperAmount);

    }

    /**
     * 补币更新操作
     *
     * @param supplementCurrencyDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSwStTvmSupplementCurrency(SwStTvmSupplementCurrencyDTO supplementCurrencyDTO,String cashBoxType) {
        SwStTvmSupplementCurrency supplementCurrency = supplementCurrencyDTO.getSupplementCurrency();
        Integer rid = supplementCurrency.getId();

        //修改之前添加记录表（先添加主表）
        SwStTvmSupplementCurrency oldSupplementCurrency = getById(rid);
        if("1".equals(oldSupplementCurrency.getReportModifyStatus())) {
            //List<SwStmStationDataEntryLog> list = new ArrayList<>();
            PigxUser user = SecurityUtils.getUser();
            oldSupplementCurrency.setEntryUpdateJobNo(user.getUserCode());
            oldSupplementCurrency.setEntryUpdateJobName(user.getNikeName());
            oldSupplementCurrency.setEntryUpdateTime(new Date());
            SwStmStationDataEntryLog swStmStationDataEntryLog = new SwStmStationDataEntryLog();
            swStmStationDataEntryLog.setRelationId(oldSupplementCurrency.getId());
            swStmStationDataEntryLog.setLogTableName(StmTableCommon.SW_ST_TVM_SUPPLEMENT_CURRENCY);
            swStmStationDataEntryLog.setLogInfo(JSONObject.toJSONString(oldSupplementCurrency));
            swStmStationDataEntryLog.setUpdateJobNo(user.getUserCode());
            swStmStationDataEntryLog.setUpdateJobName(user.getNikeName());
            swStmStationDataEntryLog.setUpdateTime(new Date());
            //list.add(swStmStationDataEntryLog);
            swStmStationDataEntryLogService.save(swStmStationDataEntryLog);

            //修改之前添加记录表（再添加子表）
            List<SwStmStationDataEntryLog> list = new ArrayList<>();
            List<SwStTvmSupplementCurrencyDetails> swStTvmSupplementCurrencyDetails = detailsService.list(
                    Wrappers.<SwStTvmSupplementCurrencyDetails>lambdaQuery()
                            .eq(SwStTvmSupplementCurrencyDetails::getRelationId, oldSupplementCurrency.getId())
                            //.eq(SwStTvmSupplementCurrencyDetails::getReportModifyStatus, "1")
                            .eq(SwStTvmSupplementCurrencyDetails::getDelFlag,0));

            if(CollectionUtil.isNotEmpty(swStTvmSupplementCurrencyDetails)){

                swStTvmSupplementCurrencyDetails.stream().forEach(currencyDetail -> {
                    currencyDetail.setEntryUpdateJobNo(user.getUserCode());
                    currencyDetail.setEntryUpdateJobName(user.getNikeName());
                    currencyDetail.setEntryUpdateTime(new Date());

                    SwStmStationDataEntryLog swStmStationDataEntryLogChild = new SwStmStationDataEntryLog();
                    swStmStationDataEntryLogChild.setRelationId(oldSupplementCurrency.getId());
                    swStmStationDataEntryLogChild.setLogTableName(StmTableCommon.SW_ST_TVM_SUPPLEMENT_CURRENCY_DETAILS);
                    swStmStationDataEntryLogChild.setMainId(swStmStationDataEntryLog.getId());//记录表id
                    swStmStationDataEntryLogChild.setLogInfo(JSONObject.toJSONString(currencyDetail));
                    swStmStationDataEntryLogChild.setUpdateJobNo(user.getUserCode());
                    swStmStationDataEntryLogChild.setUpdateJobName(user.getNikeName());
                    swStmStationDataEntryLogChild.setUpdateTime(new Date());
                    list.add(swStmStationDataEntryLogChild);
                });
            }
            swStmStationDataEntryLogService.saveBatch(list);

        }
        List<SwStTvmSupplementCurrencyDetails> details = supplementCurrencyDTO.getDetails();
        //需要注意这里的更新是有可能新增或者删除的  所以需要维护所有的更新删除场景
        List<SwStTvmSupplementCurrencyDetails> updateData = new ArrayList<>();
        List<SwStTvmSupplementCurrencyDetails> insertData = new ArrayList<>();
        for (SwStTvmSupplementCurrencyDetails detail : details) {
            if (detail.getId() != null) {
                //detail.setTvmCashBoxNum(BeanUtilsStm.strRemoveBlank(detail.getTvmCashBoxNum()));
                updateData.add(detail);
            } else {
                insertData.add(detail);
            }
        }
        List<SwStTvmSupplementCurrencyDetails> removeList = new ArrayList<>();
        if(Objects.equals(cashBoxType,"2")){
            List<SwStTvmSupplementCurrencyDetails> orginList = detailsService.list(new QueryWrapper<SwStTvmSupplementCurrencyDetails>().eq("RELATION_ID", rid).eq("TVM_CASH_BOX_TYpe","2").eq("DEL_FLAG", 0));
            List<Integer> updateIds = updateData.stream().map(x -> x.getId()).collect(Collectors.toList());
            for (SwStTvmSupplementCurrencyDetails currencyDetails : orginList) {
                if (!updateIds.contains(currencyDetails.getId())) {
                    removeList.add(currencyDetails);
                }
            }
        }
        if(Objects.equals(cashBoxType,"4")){
            List<SwStTvmSupplementCurrencyDetails> orginList = detailsService.list(new QueryWrapper<SwStTvmSupplementCurrencyDetails>().eq("RELATION_ID", rid).eq("TVM_CASH_BOX_TYpe","4").eq("DEL_FLAG", 0));
            List<Integer> updateIds = updateData.stream().map(x -> x.getId()).collect(Collectors.toList());
            for (SwStTvmSupplementCurrencyDetails currencyDetails : orginList) {
                if (!updateIds.contains(currencyDetails.getId())) {
                    removeList.add(currencyDetails);
                }
            }
        }
        if(Objects.equals(cashBoxType,"24")){
            List<SwStTvmSupplementCurrencyDetails> orginList = detailsService.list(new QueryWrapper<SwStTvmSupplementCurrencyDetails>().eq("RELATION_ID", rid).eq("DEL_FLAG", 0));
            List<Integer> updateIds = updateData.stream().map(x -> x.getId()).collect(Collectors.toList());
            for (SwStTvmSupplementCurrencyDetails currencyDetails : orginList) {
                if (!updateIds.contains(currencyDetails.getId())) {
                    removeList.add(currencyDetails);
                }
            }
        }
        //更新updateData数据
        if (CollectionUtil.isNotEmpty(updateData)) {
            detailsService.updateBatchById(updateData);
        }
        //更新删除数据
        if (CollectionUtil.isNotEmpty(removeList)) {
            removeList.forEach(x -> x.setDelFlag(CommonConstants.STATUS_DEL));
            detailsService.updateBatchById(removeList);
        }
        //更新insertData数据
        if (CollectionUtil.isNotEmpty(insertData)) {
            insertData.forEach(x -> {
                x.setRelationId(rid);
                //x.setTvmCashBoxNum(BeanUtilsStm.strRemoveBlank(x.getTvmCashBoxNum()));
            });
            detailsService.saveBatch(insertData);
        }
        //保存主表数据
		//4.1.设置主表的更新人编号和名称，为报表差错做准备
		PigxUser user = SecurityUtils.getUser();           
        supplementCurrency.setEntryUpdateJobNo(user.getUserCode());
		supplementCurrency.setEntryUpdateJobName(user.getNikeName());	

        countCoinAndPaperAmount(supplementCurrency, details);
        updateById(supplementCurrency);
        return true;
    }


    /**
     * 级联删除补币数据
     * @param id
     * @return
     */
    @Override
    public boolean deleteCascadeById(Integer id) {
        removeById(id);
        List<SwStTvmSupplementCurrencyDetails> orginList = detailsService.list(new QueryWrapper<SwStTvmSupplementCurrencyDetails>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        if (CollectionUtil.isNotEmpty(orginList)) {
            orginList.forEach(x -> x.setDelFlag(CommonConstants.STATUS_DEL));
            detailsService.updateBatchById(orginList);
        }
        return true;
    }

    @Override
    public SwStTvmSupplementCurrencyDTO queryDetailsByid(Integer id) {
        SwStTvmSupplementCurrencyDTO supplementCurrencyDTO = new SwStTvmSupplementCurrencyDTO();
        SwStTvmSupplementCurrency supplementCurrency = getById(id);
        supplementCurrencyDTO.setSupplementCurrency(supplementCurrency);
        List<SwStTvmSupplementCurrencyDetails> currencyDetails = detailsService.list(new QueryWrapper<SwStTvmSupplementCurrencyDetails>().eq("RELATION_ID", id).eq("DEL_FLAG", 0));
        if (CollectionUtil.isNotEmpty(currencyDetails)) {
            supplementCurrencyDTO.setDetails(currencyDetails);
        }
        return supplementCurrencyDTO;
    }

    @Override
    public SwStTvmSupplementCurrencyDTO queryCoinDetailsByid(Integer id) {
        SwStTvmSupplementCurrencyDTO supplementCurrencyDTO = new SwStTvmSupplementCurrencyDTO();
        SwStTvmSupplementCurrency supplementCurrency = getById(id);
        supplementCurrencyDTO.setSupplementCurrency(supplementCurrency);
        List<SwStTvmSupplementCurrencyDetails> currencyDetails = detailsService.list(new QueryWrapper<SwStTvmSupplementCurrencyDetails>().eq("RELATION_ID", id).eq("TVM_CASH_BOX_TYpe","2").eq("DEL_FLAG", 0));
        if (CollectionUtil.isNotEmpty(currencyDetails)) {
            supplementCurrencyDTO.setDetails(currencyDetails);
        }
        return supplementCurrencyDTO;
    }

    @Override
    public SwStTvmSupplementCurrencyDTO queryPaperDetailsByid(Integer id) {
        SwStTvmSupplementCurrencyDTO supplementCurrencyDTO = new SwStTvmSupplementCurrencyDTO();
        SwStTvmSupplementCurrency supplementCurrency = getById(id);
        supplementCurrencyDTO.setSupplementCurrency(supplementCurrency);
        List<SwStTvmSupplementCurrencyDetails> currencyDetails = detailsService.list(new QueryWrapper<SwStTvmSupplementCurrencyDetails>().eq("RELATION_ID", id).eq("TVM_CASH_BOX_TYpe","4").eq("DEL_FLAG", 0));
        if (CollectionUtil.isNotEmpty(currencyDetails)) {
            supplementCurrencyDTO.setDetails(currencyDetails);
        }
        return supplementCurrencyDTO;
    }
}
